﻿define(function (require, exports, moudles) {
    var hammer = require('hammer');
    return function (jquery) {
        (function ($) {
            var methods = {
                init: function (options) {
                    var defaults = {
                        menuWidth: 240,
                        edge: 'left',
                        closeOnClick: false
                    };
                    options = $.extend(defaults, options);

                    $(this).each(function () {
                        var $this = $(this);
                        var menu_id = $("#" + $this.attr('data-activates'));

                        // Set to width
                        if (options.menuWidth != 240) {
                            menu_id.css('width', options.menuWidth);
                        }

                        // Add Touch Area
                        var dragTarget = $('<div class="drag-target"></div>');
                        $('body').append(dragTarget);

                        if (options.edge == 'left') {
                            menu_id.css('left', -1 * (options.menuWidth + 10));
                            dragTarget.css({ 'left': 0 }); // Add Touch Area
                        }
                        else {
                            menu_id.addClass('right-aligned') // Change text-alignment to right
                              .css('right', -1 * (options.menuWidth + 10))
                              .css('left', '');
                            dragTarget.css({ 'right': 0 }); // Add Touch Area
                        }

                        // If fixed sidenav, bring menu out
                        if (menu_id.hasClass('fixed')) {
                            if (window.innerWidth > 992) {
                                menu_id.css('left', 0);
                            }
                        }

                        // Window resize to reset on large screens fixed
                        if (menu_id.hasClass('fixed')) {
                            $(window).resize(function () {
                                if (window.innerWidth > 992) {
                                    // Close menu if window is resized bigger than 992 and user has fixed sidenav
                                    if ($('#sidenav-overlay').css('opacity') !== 0 && menuOut) {
                                        removeMenu(true);
                                    }
                                    else {
                                        menu_id.removeAttr('style');
                                        menu_id.css('width', options.menuWidth);
                                    }
                                }
                                else if (menuOut === false) {
                                    if (options.edge === 'left')
                                        menu_id.css('left', -1 * (options.menuWidth + 10));
                                    else
                                        menu_id.css('right', -1 * (options.menuWidth + 10));
                                }

                            });
                        }

                        // if closeOnClick, then add close event for all a tags in side sideNav
                        if (options.closeOnClick === true) {
                            menu_id.on("click.itemclick", "a:not(.collapsible-header)", function () {
                                removeMenu();
                            });
                        }

                        function removeMenu(restoreNav) {
                            panning = false;
                            menuOut = false;

                            // Reenable scrolling
                            $('body').css('overflow', '');

                            $('#sidenav-overlay').velocity({ opacity: 0 }, {
                                duration: 200, queue: false, easing: 'easeOutQuad',
                                complete: function () {
                                    $(this).remove();
                                }
                            });
                            if (options.edge === 'left') {
                                // Reset phantom div
                                dragTarget.css({ width: '', right: '', left: '0' });
                                menu_id.velocity(
                                  { left: -1 * (options.menuWidth + 10) },
                                  {
                                      duration: 200,
                                      queue: false,
                                      easing: 'easeOutCubic',
                                      complete: function () {
                                          if (restoreNav === true) {
                                              // Restore Fixed sidenav
                                              menu_id.removeAttr('style');
                                              menu_id.css('width', options.menuWidth);
                                          }
                                      }

                                  });
                            }
                            else {
                                // Reset phantom div
                                dragTarget.css({ width: '', right: '0', left: '' });
                                menu_id.velocity(
                                  { right: -1 * (options.menuWidth + 10) },
                                  {
                                      duration: 200,
                                      queue: false,
                                      easing: 'easeOutCubic',
                                      complete: function () {
                                          if (restoreNav === true) {
                                              // Restore Fixed sidenav
                                              menu_id.removeAttr('style');
                                              menu_id.css('width', options.menuWidth);
                                          }
                                      }
                                  });
                            }
                        }

                        // Touch Event
                        var panning = false;
                        var menuOut = false;

                        dragTarget.on('click', function () {
                            removeMenu();
                        });

                        dragTarget.hammer({
                            prevent_default: false
                        }).bind('pan', function (e) {

                            if (e.gesture.pointerType == "touch") {

                                var direction = e.gesture.direction;
                                var x = e.gesture.center.x;
                                var y = e.gesture.center.y;
                                var velocityX = e.gesture.velocityX;

                                // Disable Scrolling
                                $('body').css('overflow', 'hidden');

                                // If overlay does not exist, create one and if it is clicked, close menu
                                if ($('#sidenav-overlay').length === 0) {
                                    var overlay = $('<div id="sidenav-overlay"></div>');
                                    overlay.css('opacity', 0).click(function () {
                                        removeMenu();
                                    });
                                    $('body').append(overlay);
                                }

                                // Keep within boundaries
                                if (options.edge === 'left') {
                                    if (x > options.menuWidth) { x = options.menuWidth; }
                                    else if (x < 0) { x = 0; }
                                }

                                if (options.edge === 'left') {
                                    // Left Direction
                                    if (x < (options.menuWidth / 2)) { menuOut = false; }
                                        // Right Direction
                                    else if (x >= (options.menuWidth / 2)) { menuOut = true; }

                                    menu_id.css('left', (x - options.menuWidth));
                                }
                                else {
                                    // Left Direction
                                    if (x < (window.innerWidth - options.menuWidth / 2)) {
                                        menuOut = true;
                                    }
                                        // Right Direction
                                    else if (x >= (window.innerWidth - options.menuWidth / 2)) {
                                        menuOut = false;
                                    }
                                    var rightPos = -1 * (x - options.menuWidth / 2);
                                    if (rightPos > 0) {
                                        rightPos = 0;
                                    }

                                    menu_id.css('right', rightPos);
                                }

                                // Percentage overlay
                                var overlayPerc;
                                if (options.edge === 'left') {
                                    overlayPerc = x / options.menuWidth;
                                    $('#sidenav-overlay').velocity({ opacity: overlayPerc }, { duration: 50, queue: false, easing: 'easeOutQuad' });
                                }
                                else {
                                    overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth);
                                    $('#sidenav-overlay').velocity({ opacity: overlayPerc }, { duration: 50, queue: false, easing: 'easeOutQuad' });
                                }
                            }

                        }).bind('panend', function (e) {

                            if (e.gesture.pointerType == "touch") {
                                var velocityX = e.gesture.velocityX;
                                panning = false;
                                if (options.edge === 'left') {
                                    // If velocityX <= 0.3 then the user is flinging the menu closed so ignore menuOut
                                    if ((menuOut && velocityX <= 0.3) || velocityX < -0.5) {
                                        menu_id.velocity({ left: 0 }, { duration: 300, queue: false, easing: 'easeOutQuad' });
                                        $('#sidenav-overlay').velocity({ opacity: 1 }, { duration: 50, queue: false, easing: 'easeOutQuad' });
                                        dragTarget.css({ width: '50%', right: 0, left: '' });
                                    }
                                    else if (!menuOut || velocityX > 0.3) {
                                        // Enable Scrolling
                                        $('body').css('overflow', '');
                                        // Slide menu closed
                                        menu_id.velocity({ left: -1 * (options.menuWidth + 10) }, { duration: 200, queue: false, easing: 'easeOutQuad' });
                                        $('#sidenav-overlay').velocity({ opacity: 0 }, {
                                            duration: 200, queue: false, easing: 'easeOutQuad',
                                            complete: function () {
                                                $(this).remove();
                                            }
                                        });
                                        dragTarget.css({ width: '10px', right: '', left: 0 });
                                    }
                                }
                                else {
                                    if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) {
                                        menu_id.velocity({ right: 0 }, { duration: 300, queue: false, easing: 'easeOutQuad' });
                                        $('#sidenav-overlay').velocity({ opacity: 1 }, { duration: 50, queue: false, easing: 'easeOutQuad' });
                                        dragTarget.css({ width: '50%', right: '', left: 0 });
                                    }
                                    else if (!menuOut || velocityX < -0.3) {
                                        // Enable Scrolling
                                        $('body').css('overflow', '');
                                        // Slide menu closed
                                        menu_id.velocity({ right: -1 * (options.menuWidth + 10) }, { duration: 200, queue: false, easing: 'easeOutQuad' });
                                        $('#sidenav-overlay').velocity({ opacity: 0 }, {
                                            duration: 200, queue: false, easing: 'easeOutQuad',
                                            complete: function () {
                                                $(this).remove();
                                            }
                                        });
                                        dragTarget.css({ width: '10px', right: 0, left: '' });
                                    }
                                }

                            }
                        });

                        $this.click(function () {
                            if (menuOut === true) {
                                menuOut = false;
                                panning = false;
                                removeMenu();
                            }
                            else {

                                // Disable Scrolling
                                $('body').css('overflow', 'hidden');
                                // Push current drag target on top of DOM tree
                                $('body').append(dragTarget);

                                if (options.edge === 'left') {
                                    dragTarget.css({ width: '50%', right: 0, left: '' });
                                    menu_id.velocity({ left: 0 }, { duration: 300, queue: false, easing: 'easeOutQuad' });
                                }
                                else {
                                    dragTarget.css({ width: '50%', right: '', left: 0 });
                                    menu_id.velocity({ right: 0 }, { duration: 300, queue: false, easing: 'easeOutQuad' });
                                    menu_id.css('left', '');
                                }

                                var overlay = $('<div id="sidenav-overlay"></div>');
                                overlay.css('opacity', 0)
                                .click(function () {
                                    menuOut = false;
                                    panning = false;
                                    removeMenu();
                                    overlay.velocity({ opacity: 0 }, {
                                        duration: 300, queue: false, easing: 'easeOutQuad',
                                        complete: function () {
                                            $(this).remove();
                                        }
                                    });

                                });
                                $('body').append(overlay);
                                overlay.velocity({ opacity: 1 }, {
                                    duration: 300, queue: false, easing: 'easeOutQuad',
                                    complete: function () {
                                        menuOut = true;
                                        panning = false;
                                    }
                                });
                            }

                            return false;
                        });
                    });
                },
                show: function () {
                    this.trigger('click');
                },
                hide: function () {
                    $('#sidenav-overlay').trigger('click');
                }
            };
            $.fn.sideNav = function (methodOrOptions) {
                if (methods[methodOrOptions]) {
                    return methods[methodOrOptions].apply(this, Array.prototype.slice.call(arguments, 1));
                } else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
                    // Default to "init"
                    return methods.init.apply(this, arguments);
                } else {
                    $.error('Method ' + methodOrOptions + ' does not exist on jQuery.sideNav');
                }
            }; // Plugin end
            $(function () {
                //Main Left Sidebar Menu
                $('.sidebar-collapse').sideNav({
                    edge: 'left', // Choose the horizontal origin    
                });
            });
        })(jquery);
    }
})